﻿namespace WinnerCMS.Common.Security
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Threading;

    internal static class UrlEncoder
    {
        private static char[][] characterValues;
        private static readonly ReaderWriterLockSlim SyncLock = new ReaderWriterLockSlim();

        private static void AcquireReadLock()
        {
            SyncLock.EnterReadLock();
        }

        private static void AcquireWriteLock()
        {
            SyncLock.EnterWriteLock();
        }

        private static bool AreNextTwoCharactersValidHexString(byte[] input, int position)
        {
            if ((position >= input.Length) || ((position + 1) >= input.Length))
            {
                return false;
            }
            return (IsValidHexCharacter((char) input[position]) && IsValidHexCharacter((char) input[position + 1]));
        }

        private static void InitializeSafeList()
        {
            AcquireWriteLock();
            try
            {
                if (characterValues == null)
                {
                    characterValues = SafeList.Generate(0xff, new SafeList.GenerateSafeValue(SafeList.PercentThenHexValueGenerator));
                    SafeList.PunchSafeList(ref characterValues, UrlSafeList());
                }
            }
            finally
            {
                ReleaseWriteLock();
            }
        }

        private static bool IsValidHexCharacter(char c)
        {
            bool flag = (c >= '0') && (c <= '9');
            bool flag2 = (c >= 'A') && (c <= 'F');
            bool flag3 = (c >= 'a') && (c <= 'f');
            if (!flag && !flag3)
            {
                return flag2;
            }
            return true;
        }

        internal static string PathEncode(string s)
        {
            if (string.IsNullOrEmpty(s))
            {
                return s;
            }
            if (characterValues == null)
            {
                InitializeSafeList();
            }
            string[] strArray = s.Split("?".ToCharArray());
            string str = strArray[0];
            string str2 = string.Empty;
            if (strArray.Length == 2)
            {
                str2 = "?" + strArray[1];
            }
            byte[] bytes = Encoding.UTF8.GetBytes(str.ToCharArray());
            int length = 0;
            int num2 = bytes.Length;
            char[] chArray = new char[num2 * 3];
            AcquireReadLock();
            try
            {
                for (int i = 0; i < num2; i++)
                {
                    byte index = bytes[i];
                    if ((index == 0x25) && AreNextTwoCharactersValidHexString(bytes, i + 1))
                    {
                        chArray[length++] = (char) bytes[i++];
                        chArray[length++] = (char) bytes[i++];
                        chArray[length++] = (char) bytes[i];
                    }
                    else if (characterValues[index] != null)
                    {
                        char[] chArray2 = characterValues[index];
                        for (int j = 0; j < chArray2.Length; j++)
                        {
                            chArray[length++] = chArray2[j];
                        }
                    }
                    else
                    {
                        chArray[length++] = (char) index;
                    }
                }
            }
            finally
            {
                ReleaseReadLock();
            }
            return (new string(chArray, 0, length) + str2);
        }

        private static void ReleaseReadLock()
        {
            SyncLock.ExitReadLock();
        }

        private static void ReleaseWriteLock()
        {
            SyncLock.ExitWriteLock();
        }

        private static IEnumerable<int> UrlSafeList()
        {
            int iteratorVariable0 = 0x30;
        Label_PostSwitchInIterator:;
            if (iteratorVariable0 <= 0x39)
            {
                yield return iteratorVariable0;
                iteratorVariable0++;
                goto Label_PostSwitchInIterator;
            }
            for (int i = 0x41; i <= 90; i++)
            {
                yield return i;
            }
            for (int j = 0x61; j <= 0x7a; j++)
            {
                yield return j;
            }
            yield return 0x2d;
            yield return 0x5f;
            yield return 0x2e;
            yield return 0x7e;
            yield return 0x21;
            yield return 0x2a;
            yield return 0x5c;
            yield return 40;
            yield return 0x29;
            yield return 0x2c;
            yield return 0x2f;
        }

    }
}

